package com.drg.center.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.drg.center.dao.*;
import com.drg.center.entity.*;
import com.drg.center.entity.enums.UserAccTypeEnum;
import com.drg.center.entity.enums.UserStatusEnum;
import com.drg.center.entity.param.*;
import com.drg.center.entity.result.SysDeptVO;
import com.drg.center.entity.result.SysUserExtVO;
import com.drg.center.entity.result.SysUserListVO;
import com.drg.center.entity.result.SysUserVO;
import com.google.common.collect.Maps;
import com.guaike.core.entity.constant.ViewConstant;
import com.guaike.core.entity.context.ContextHolder;
import com.guaike.core.entity.enums.DataPermissonTypeEnum;
import com.guaike.core.entity.exception.ApiException;
import com.guaike.core.entity.result.PageEntity;
import com.guaike.core.entity.result.Result;
import com.guaike.core.utils.CompareUtil;
import com.guaike.core.utils.ListUtil;
import com.guaike.core.utils.MD5Utils;
import com.guaike.core.utils.PasswordUtils;
import com.drg.center.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.mapping.ResultFlag;
import org.assertj.core.util.Lists;
import org.assertj.core.util.Sets;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Author: zhangxilin
 * @Date: 2024/5/22
 */
@Slf4j
@Service
public class SysUserServiceImpl implements SysUserService {

    @Autowired
    private SysUserDAO sysUserDAO;
    @Autowired
    private SysDepartDAO sysDeptDAO;
    @Autowired
    private SysUserScopeDAO sysUserScopeDAO;
    @Autowired
    private SysUserDeptDAO sysUserDeptDAO;
    @Autowired
    private SysRoleDAO sysRoleDAO;
    @Autowired
    private SysUserRoleDAO sysUserRoleDAO;
    @Autowired
    private SysPositionDAO sysPositionDAO;
    @Autowired
    private SysUserPositionDAO sysUserPositionDAO;

    @Autowired
    private DataSourceTransactionManager transactionManager;
    @Autowired
    private TransactionDefinition transactionDefinition;


    @Override
    public Result<Boolean> add(SysUserAddDTO param) {
        String password = decodeStr(param.getPassword());
        if(!isPassword(password)){
            return Result.failure().message("密码必须由8-20数字+字母(区分大小写)组成,可包含特殊字符").build();
        }
        if(sysUserDAO.isExist(SysUserPO::getUsername, param.getUsername(), SysUserPO::getId, null)){
            return Result.failure().message("账号已存在").build();
        }
        Set<String> deptSet = getDeptSet(param.getDeptCode(), param.getDeptCodeList(), param.getScopeDeptCodeList());
        if(StringUtils.isNotBlank(param.getDeptCode()) && ! deptSet.contains(param.getDeptCode())){
            return Result.failure().message("所属部门不存在").build();
        }

        SysUserPO record = new SysUserPO();
        setUserAttr(record,param);
        record.setPassword(PasswordUtils.encrypt(password));

        List<SysUserDeptPO> userDeptList = getUserDeptList(null, param.getDeptCode(),  param.getDeptCodeList(), deptSet);
        List<SysUserScopePO> scopePOList = getScopeList(null, param.getScopeType(), param.getScopeDeptCodeList(), deptSet);
        List<SysUserRolePO> userRolePOList = getUserRolePOList(null, param.getRoleIdList());
        List<SysUserPositionPO> userPositionPOList = getSysUserPositionPOList(null, param.getPositionIdList());


        TransactionStatus transactionStatus= transactionManager.getTransaction(transactionDefinition);
        try{
            sysUserDAO.save(record);
            if(!CollectionUtils.isEmpty(userDeptList)){
                userDeptList.forEach(item -> item.setUserId(record.getId()));
                sysUserDeptDAO.saveBatch(userDeptList);
            }
            if(!CollectionUtils.isEmpty(scopePOList)){
                scopePOList.forEach(item -> item.setUserId(record.getId()));
                sysUserScopeDAO.saveBatch(scopePOList);
            }
            if(!CollectionUtils.isEmpty(userRolePOList)){
                userRolePOList.forEach(item -> item.setUserId(record.getId()));
                sysUserRoleDAO.saveBatch(userRolePOList);
            }
            if(!CollectionUtils.isEmpty(userPositionPOList)){
                userPositionPOList.forEach(item -> item.setUserId(record.getId()));
                sysUserPositionDAO.saveBatch(userPositionPOList);
            }
            transactionManager.commit(transactionStatus);
        }catch (Exception e){
            log.error("执行事务异常，需要回滚 e:{}",e);
            transactionManager.rollback(transactionStatus);
            throw new ApiException(e.getMessage());
        }

        return Result.success().data(Boolean.TRUE).build();
    }

    @Override
    public Result<Boolean> edit(SysUserEditDTO param) {

        if(sysUserDAO.isExist(SysUserPO::getUsername, param.getUsername(), SysUserPO::getId, param.getId())){
            return Result.failure().message("账号已存在").build();
        }
        Set<String> deptSet = getDeptSet(param.getDeptCode(), param.getDeptCodeList(), param.getScopeDeptCodeList());
        if(StringUtils.isNotBlank(param.getDeptCode()) && !deptSet.contains(param.getDeptCode())){
            return Result.failure().message("所属部门不存在").build();
        }

        SysUserPO record = sysUserDAO.findById(param.getId());
        if(record == null){
            return Result.failure().message("记录不存在").build();
        }
        setUserAttr(record,param);

        List<SysUserDeptPO> userDeptList = getUserDeptList(param.getId(), param.getDeptCode(),  param.getDeptCodeList(), deptSet);
        List<SysUserScopePO> scopePOList = getScopeList(param.getId(), param.getScopeType(), param.getScopeDeptCodeList(), deptSet);
        List<SysUserRolePO> userRolePOList = getUserRolePOList(param.getId(), param.getRoleIdList());
        List<SysUserPositionPO> userPositionPOList = getSysUserPositionPOList(param.getId(), param.getPositionIdList());


        TransactionStatus transactionStatus= transactionManager.getTransaction(transactionDefinition);
        try{
            sysUserDAO.updateById(record);

            sysUserDeptDAO.del(SysUserDeptPO::getUserId, param.getId());
            sysUserScopeDAO.del(SysUserScopePO::getUserId, param.getId());
            sysUserRoleDAO.del(SysUserRolePO::getUserId, param.getId());
            sysUserPositionDAO.del(SysUserPositionPO::getUserId, param.getId());


            if(!CollectionUtils.isEmpty(userDeptList)){
                sysUserDeptDAO.saveBatch(userDeptList);
            }
            if(!CollectionUtils.isEmpty(scopePOList)){
                sysUserScopeDAO.saveBatch(scopePOList);
            }
            if(!CollectionUtils.isEmpty(userRolePOList)){
                sysUserRoleDAO.saveBatch(userRolePOList);
            }
            if(!CollectionUtils.isEmpty(userPositionPOList)){
                sysUserPositionDAO.saveBatch(userPositionPOList);
            }
            transactionManager.commit(transactionStatus);
        }catch (Exception e){
            log.error("执行事务异常，需要回滚 e:{}",e);
            transactionManager.rollback(transactionStatus);
            throw new ApiException(e.getMessage());
        }
        return Result.success().data(Boolean.TRUE).build();
    }

    @Override
    public Result<PageEntity<SysUserListVO>> page(SysUserListDTO param) {
        Set<Long> userIdSet = getUserIdList(param.getDeptCode());
        if(StringUtils.isNotBlank(param.getDeptCode()) && CollectionUtils.isEmpty(userIdSet)){
            return Result.success().data(new PageEntity<>(0L, Lists.newArrayList())).build();
        }
        IPage<SysUserPO> iPage = sysUserDAO.findPage(param, userIdSet);
        if(CollectionUtils.isEmpty(iPage.getRecords())){
            return Result.success().data(new PageEntity<>(0L, Lists.newArrayList())).build();
        }
        List<Long> userIdList = iPage.getRecords().stream().map(SysUserPO::getId).collect(Collectors.toList());
        Map<Long, String> positionMap = getPositionMap(userIdList);
        Map<Long, String> roleMap = getRoleMap(userIdList);
        Map<Long, Set<String>> deptMap = getDeptMap(userIdList, iPage.getRecords());

        List<SysUserListVO> list = Lists.newArrayList();
        for(SysUserPO po: iPage.getRecords()){
            SysUserListVO vo = new SysUserListVO();
            vo.setId(po.getId());
            vo.setUsername(po.getUsername());
            vo.setRealName(po.getRealName());
            vo.setPhone(po.getPhone());
            vo.setStatus(po.getStatus());
            vo.setScopeType(po.getScopeType());
            vo.setRoleNameStr(roleMap.get(po.getId()));
            vo.setPositionStr(positionMap.get(po.getId()));
            if(po.getFrozenExpire() != null && po.getFrozenExpire().compareTo(System.currentTimeMillis()) >0){
                vo.setFrozenExpireDate(LocalDateTimeUtil.of(po.getFrozenExpire()));
                vo.setFrozenReason(po.getFrozenReason());
            }

            Set<String> deptNameSet = deptMap.get(po.getId());
            if(!CollectionUtils.isEmpty(deptNameSet)){
                vo.setDeptName(StringUtils.join(deptNameSet, ViewConstant.COMMA_DISP));
            }
            list.add(vo);
        }
        return Result.success().data(new PageEntity<>(iPage.getTotal(), list)).build();
    }

    private Map<Long, String> getRoleMap(List<Long> userIdList){
        if(CollectionUtils.isEmpty(userIdList)){
            return Maps.newHashMap();
        }
        List<SysUserRolePO> userRolePOList = sysUserRoleDAO.findIn(SysUserRolePO::getUserId, userIdList);
        if(CollectionUtils.isEmpty(userRolePOList)){
            return Maps.newHashMap();
        }
        Set<Long> roleIdSet =userRolePOList.stream().map(SysUserRolePO::getRoleId).collect(Collectors.toSet());
        List<SysRolePO> rolePOList = sysRoleDAO.findByIdList(roleIdSet);
        if(CollectionUtils.isEmpty(rolePOList)){
            return Maps.newHashMap();
        }
        Map<Long, String> roleMap = rolePOList.stream().collect(Collectors.toMap(SysRolePO::getId, SysRolePO::getRoleName));
        Map<Long,List<SysUserRolePO>> groupByUserMap = userRolePOList.stream().collect(Collectors.groupingBy(SysUserRolePO::getUserId));

        Map<Long, String> map = Maps.newHashMap();
        for(Map.Entry<Long, List<SysUserRolePO>> entry: groupByUserMap.entrySet()){
            List<String> roleList = Lists.newArrayList();
            for(SysUserRolePO po: entry.getValue()){
                roleList.add(roleMap.get(po.getRoleId()));
            }
            map.put(entry.getKey(), StringUtils.join(roleList,ViewConstant.COMMA_DISP));
        }
        return map;
    }

    private Map<Long, Set<String>> getDeptMap(List<Long> userIdList, List<SysUserPO> userPOList){
        if(CollectionUtils.isEmpty(userIdList)){
            return Maps.newHashMap();
        }
        List<SysUserDeptPO> userDeptPOList=  sysUserDeptDAO.findIn(SysUserDeptPO::getUserId, userIdList);
        if(CollectionUtils.isEmpty(userDeptPOList)){
            return Maps.newHashMap();
        }
        Map<Long, String> mainDeptMap = userPOList.stream().collect(Collectors.toMap(SysUserPO::getId, SysUserPO::getDeptCode));
        Map<Long, List<SysUserDeptPO>> userDeptGroup=  userDeptPOList.stream().collect(Collectors.groupingBy(SysUserDeptPO::getUserId));

        Set<String> deptIdSet = userDeptPOList.stream().map(SysUserDeptPO::getDeptCode).collect(Collectors.toSet());
        List<SysDepartPO> poList = sysDeptDAO.findListByCodeList(deptIdSet);
        Map<String, String> deptMap = poList.stream().collect(Collectors.toMap(SysDepartPO::getDepartCode, SysDepartPO::getDepartName));

        Map<Long, Set<String>> map = Maps.newHashMap();
        for(Map.Entry<Long, List<SysUserDeptPO>> entry: userDeptGroup.entrySet()){
            List<SysUserDeptPO> byUserPOList = entry.getValue();
            if(CollectionUtils.isEmpty(byUserPOList)){
                continue;
            }
            Set<String> set = Sets.newHashSet();
            for(SysUserDeptPO po: byUserPOList){
                String deptName = deptMap.get(po.getDeptCode());
                if(StringUtils.isBlank(deptName)){
                    continue;
                }
                String mainDeptId = mainDeptMap.get(po.getUserId());
                if(StringUtils.isNotBlank(po.getDeptCode()) && byUserPOList.size()>1 && CompareUtil.isEqual(mainDeptId, po.getDeptCode())){
                    deptName = StrUtil.format("{}(主)",deptName);
                }
                set.add(deptName);
            }
            map.put(entry.getKey(), set);
        }
        return map;
    }

    private Map<Long, String> getPositionMap(List<Long> userIdList){
        if(CollectionUtils.isEmpty(userIdList)){
            return Maps.newHashMap();
        }
        List<SysUserPositionPO> userPositionPOList = sysUserPositionDAO.findIn(SysUserPositionPO::getUserId,userIdList);
        if(CollectionUtils.isEmpty(userPositionPOList)){
            return Maps.newHashMap();
        }
        Set<Long> positionIdSet = userPositionPOList.stream().map(SysUserPositionPO::getPositionId).collect(Collectors.toSet());
        List<SysPositionPO> positionPOList = sysPositionDAO.findByIdList(positionIdSet);
        if(CollectionUtils.isEmpty(positionPOList)){
            return Maps.newHashMap();
        }
        Map<Long, String> positionMap = positionPOList.stream().collect(Collectors.toMap(SysPositionPO::getId, SysPositionPO::getPosition));

        Map<Long,List<SysUserPositionPO>> groupByUserMap = userPositionPOList.stream().collect(Collectors.groupingBy(SysUserPositionPO::getUserId));

        Map<Long, String> map = Maps.newHashMap();
        for(Map.Entry<Long, List<SysUserPositionPO>> entry: groupByUserMap.entrySet()){
            List<String> positionList = Lists.newArrayList();
            for(SysUserPositionPO po: entry.getValue()){
                positionList.add(positionMap.get(po.getPositionId()));
            }
            map.put(entry.getKey(), StringUtils.join(positionList,ViewConstant.COMMA_DISP));
        }
        return map;
    }


    private Set<Long> getUserIdList(String deptCode){
        if(StringUtils.isBlank(deptCode)){
            return null;
        }
        SysDepartPO deptPO = sysDeptDAO.findOne(SysDepartPO::getDepartCode, deptCode);
        if(deptPO == null){
            log.warn("setUserIdListAndIsReturn, deptPO is null, deptCode: {}", deptCode);
            return null;
        }
        String traceIds = StringUtils.isBlank(deptPO.getTraces())? deptPO.getDepartCode(): deptPO.getTraces()+ ViewConstant.COMMA_DISP+  deptPO.getDepartCode();
        List<SysDepartPO> deptList = sysDeptDAO.findSubList(traceIds);
        Set<String> deptCodeSet = deptList.stream().map(SysDepartPO::getDepartCode).collect(Collectors.toSet());
        deptCodeSet.add(deptCode);

        List<SysUserDeptPO> userDeptPOList = sysUserDeptDAO.findIn(SysUserDeptPO::getDeptCode,deptCodeSet);
        return userDeptPOList.stream().map(SysUserDeptPO::getUserId).collect(Collectors.toSet());
    }


    @Override
    public Result<SysUserVO> findById(Long id) {
        SysUserPO record = sysUserDAO.findById(id);
        if(record==null){
            return Result.failure().message("记录不存在").build();
        }
        SysUserVO vo = new SysUserVO();
        BeanUtil.copyProperties(record,vo);
        return Result.success().data(vo).build();
    }

    @Override
    public Result<SysUserExtVO> detail(Long id) {
        SysUserPO po = sysUserDAO.findById(id);
        if(po==null){
            return Result.failure().message("记录不存在").build();
        }

        SysUserExtVO vo = new SysUserExtVO();
        vo.setId(po.getId());
        vo.setUsername(po.getUsername());
        vo.setRealName(po.getRealName());
        vo.setPhone(po.getPhone());
        vo.setStatus(po.getStatus());

        vo.setScopeType(po.getScopeType());
        if(CompareUtil.isEqual(po.getScopeType(), DataPermissonTypeEnum.CUSTOM.getCode())){
           List<SysUserScopePO> userScopePOList = sysUserScopeDAO.findList(SysUserScopePO::getUserId,id);
           if(!CollectionUtils.isEmpty(userScopePOList)){
               List<String> deptCodeList = userScopePOList.stream().map(SysUserScopePO::getDeptCode).collect(Collectors.toList());
               List<SysDepartPO> deptPOList = sysDeptDAO.findListByCodeList(deptCodeList);
               vo.setScopeDeptList(ListUtil.copyList(deptPOList, SysDeptVO.class));
           }
        }

        if(po.getFrozenExpire() != null && po.getFrozenExpire().compareTo(System.currentTimeMillis()) >0){
            vo.setFrozenExpireDate(LocalDateTimeUtil.of(po.getFrozenExpire()));
            vo.setFrozenReason(po.getFrozenReason());
        }
        setRole(vo, id);
        setPosition(vo, id);
        setDept(vo, po);
        return Result.success().data(vo).build();
    }

    private void setDept(SysUserExtVO vo, SysUserPO record){
        List<SysUserDeptPO> userDeptPOList = sysUserDeptDAO.findList(SysUserDeptPO::getUserId, record.getId());
        if(CollectionUtils.isEmpty(userDeptPOList)){
            return;
        }
        Set<String> deptIdSet = userDeptPOList.stream().map(SysUserDeptPO::getDeptCode).collect(Collectors.toSet());
        List<SysDepartPO> deptPOList = sysDeptDAO.findListByCodeList(deptIdSet);
        List<SysDeptVO> deptList = Lists.newArrayList();
        for(SysDepartPO po: deptPOList){
            if(CompareUtil.isEqual(po.getDepartCode(),record.getDeptCode())){
                //主部门
                vo.setMaindeptCode(po.getDepartCode());
                vo.setMainDeptName(po.getDepartName());
                continue;
            }
            SysDeptVO deptVO = new SysDeptVO();
            BeanUtil.copyProperties(po, deptVO);
            deptList.add(deptVO);
        }
        vo.setDeptList(deptList);
    }

    private void setRole(SysUserExtVO vo, Long userId){
      List<SysUserRolePO> userRolePOList =  sysUserRoleDAO.findList(SysUserRolePO::getUserId, userId);
      if(CollectionUtils.isEmpty(userRolePOList)){
          return;
      }
      Set<Long> roleIdSet = userRolePOList.stream().map(SysUserRolePO::getRoleId).collect(Collectors.toSet());
      List<SysRolePO> rolePOList = sysRoleDAO.findByIdList(roleIdSet);
      List<Long> roleIdList = Lists.newArrayList();
      List<String> roleNameList = Lists.newArrayList();
      rolePOList.forEach(item -> {
          roleIdList.add(item.getId());
          roleNameList.add(item.getRoleName());
      });
      vo.setRoleIdList(roleIdList);
      vo.setRoleNameList(roleNameList);
    }

    private void setPosition(SysUserExtVO vo, Long userId){
        List<SysUserPositionPO> userPositionPOList =  sysUserPositionDAO.findList(SysUserPositionPO::getUserId, userId);
        if(CollectionUtils.isEmpty(userPositionPOList)){
            return;
        }
        Set<Long> positionIdSet = userPositionPOList.stream().map(SysUserPositionPO::getPositionId).collect(Collectors.toSet());
        List<SysPositionPO> positionPOList = sysPositionDAO.findByIdList(positionIdSet);
        List<Long> positionIdList = Lists.newArrayList();
        List<String> positionNameList = Lists.newArrayList();
        positionPOList.forEach(item -> {
            positionIdList.add(item.getId());
            positionNameList.add(item.getPosition());
        });
        vo.setPositionIdList(positionIdList);
        vo.setPositionList(positionNameList);
    }


    @Override
    public Result<Boolean> editStatus(SysUserStatusDTO param) {
        SysUserPO record = sysUserDAO.findById(param.getId());
        if(record==null){
            return Result.failure().message("记录不存在").build();
        }
        record.setStatus(param.getStatus());
        record.setRemark(param.getRemark());
        sysUserDAO.updateById(record);
        return Result.success().data(Boolean.TRUE).build();
    }

    @Override
    public Result<Boolean> resetPwd(SysUserPwdResetDTO param) {
        SysUserPO record = sysUserDAO.findById(param.getId());
        if(record==null){
            return Result.failure().message("记录不存在").build();
        }
        String password = decodeStr(param.getPassword());
        if(!isPassword(password)){
            return Result.failure().message("密码必须由8-20数字+字母(区分大小写)组成,可包含特殊字符").build();
        }
        record.setPassword(PasswordUtils.encrypt(password));
        sysUserDAO.updateById(record);
        return Result.success().data(Boolean.TRUE).build();
    }

    @Override
    public Result<Boolean> updatePwd(SysPwdEditDTO param) {
        String oldPwd = decodeStr(param.getOldPwd());
        if(!isPassword(oldPwd)){
            return Result.failure().message("原密码必须由8-20数字+字母(区分大小写)组成,可包含特殊字符").build();
        }
        String password = decodeStr(param.getPassword());
        if(!isPassword(password)){
            return Result.failure().message("密码必须由8-20数字+字母(区分大小写)组成,可包含特殊字符").build();
        }
        SysUserPO record = sysUserDAO.findById(ContextHolder.getUserId());
        if(record==null){
            return Result.failure().message("用户记录不存在").build();
        }
        if(!checkPassword(oldPwd,record.getPassword())){
            log.error("当前账号原密码错误，username: {},  password:{}",record.getUsername(),oldPwd);
            return Result.failure().message("用户名原密码错误,请重新输入").build();
        }
        record.setPassword(PasswordUtils.encrypt(password));
        sysUserDAO.updateById(record);
        return Result.success().data(Boolean.TRUE).build();
    }

    @Override
    public Result<Boolean> updateUsername(SysUsernameEditDTO param) {
        if(StringUtils.isBlank(param.getUsername()) && StringUtils.isBlank(param.getPhone())){
            return Result.failure().message("请输入修改信息").build();
        }
        SysUserPO record = sysUserDAO.findById(ContextHolder.getUserId());
        if(record==null){
            return Result.failure().message("用户记录不存在").build();
        }
        if(StringUtils.isNotBlank(param.getUsername())){
            record.setUsername(param.getUsername());
        }
        if(StringUtils.isNotBlank(param.getPhone())){
            record.setPhone(param.getPhone());
        }
        sysUserDAO.updateById(record);
        return Result.success().data(Boolean.TRUE).build();
    }

    /**
     * 校验密码
     * @param password
     * @param dbpassword
     * @return
     */
    public Boolean checkPassword(String password,String dbpassword){
        String depwd = PasswordUtils.encrypt(password);
        return depwd.equals(dbpassword);
    }


    private void setUserAttr(SysUserPO record, SysUserAddDTO param){
        record.setUsername(param.getUsername());
        record.setRealName(param.getRealName());
        record.setPhone(param.getPhone());
        record.setStatus(UserStatusEnum.ENABLE.getCode());
        record.setAccType(UserAccTypeEnum.GENERAL_USER.getType());
        record.setScopeType(param.getScopeType()==null?null: param.getScopeType());
        record.setDeptCode(param.getDeptCode());
    }

    private void setUserAttr(SysUserPO record,SysUserEditDTO param){
        record.setUsername(param.getUsername());
        record.setRealName(param.getRealName());
        record.setPhone(param.getPhone());
        record.setScopeType(param.getScopeType()==null?null: param.getScopeType());
        record.setDeptCode(param.getDeptCode());
    }

    private List<SysUserScopePO> getScopeList(Long userId, Integer scopeType, List<String> scopeDeptCodeList, Set<String> deptSet){
        if(!CompareUtil.isEqual(scopeType, DataPermissonTypeEnum.CUSTOM.getCode())){
            return null;
        }
        if(CollectionUtils.isEmpty(scopeDeptCodeList)){
            throw new ApiException("请选择有权限的部门");
        }
        List<SysUserScopePO> list = Lists.newArrayList();
        for(String deptCode: scopeDeptCodeList){
            if(!deptSet.contains(deptCode)){
                throw new ApiException("权限部门传参不合法");
            }
            list.add(of(userId, deptCode));
        }
        return list;
    }

    private List<SysUserRolePO> getUserRolePOList(Long userId, List<Long> roleIdList){
        if(CollectionUtils.isEmpty(roleIdList)){
            return null;
        }
        List<SysRolePO> poList = sysRoleDAO.findByIdList(roleIdList);
        Set<Long> roleIdSet = poList.stream().map(SysRolePO::getId).collect(Collectors.toSet());

        List<SysUserRolePO> list = Lists.newArrayList();
        for(Long roleId: roleIdList){
            if(!roleIdSet.contains(roleId)){
                throw new ApiException("角色传参不合法");
            }
            SysUserRolePO po = new SysUserRolePO();
            po.setUserId(userId);
            po.setRoleId(roleId);
            list.add(po);
        }
        return list;
    }

    private List<SysUserPositionPO> getSysUserPositionPOList(Long userId, List<Long> positionIdList){
        if(CollectionUtils.isEmpty(positionIdList)){
            return null;
        }
        List<SysPositionPO> poList = sysPositionDAO.findByIdList(positionIdList);
        Set<Long> positionIdSet = poList.stream().map(SysPositionPO::getId).collect(Collectors.toSet());

        List<SysUserPositionPO> list = Lists.newArrayList();
        for(Long positionId: positionIdList){
            if(!positionIdSet.contains(positionId)){
                throw new ApiException("角色传参不合法");
            }
            SysUserPositionPO po = new SysUserPositionPO();
            po.setUserId(userId);
            po.setPositionId(positionId);
            list.add(po);
        }
        return list;
    }



    private List<SysUserDeptPO> getUserDeptList(Long userId, String mainDeptCode, List<String> deptCodeList, Set<String> deptSet ){
        List<SysUserDeptPO> list = Lists.newArrayList();
        if(mainDeptCode != null){
            list.add(ofUserDept(userId, mainDeptCode));
        }
        if(CollectionUtils.isEmpty(deptCodeList)){
            return list;
        }

        for(String deptCode: deptCodeList ){
            if(!deptSet.contains(deptCode)){
                throw new ApiException("部门传参不合法");
            }
            list.add(ofUserDept(userId, deptCode));
        }
        return list;
    }

    private SysUserScopePO of(Long userId, String deptCode){
        SysUserScopePO po = new SysUserScopePO();
        po.setUserId(userId);
        po.setDeptCode(deptCode);
        return po;
    }

    private SysUserDeptPO ofUserDept(Long userId, String deptCode){
        SysUserDeptPO po = new SysUserDeptPO();
        po.setUserId(userId);
        po.setDeptCode(deptCode);
        return po;
    }

    private Set<String> getDeptSet(String mainDeptId, List<String> deptIdList, List<String> scopeDeptIdList){
        List<String> deptIds = Lists.newArrayList();
        if(StringUtils.isNotBlank(mainDeptId)){
            deptIds.add(mainDeptId);
        }
        if(!CollectionUtils.isEmpty(deptIdList)){
            deptIds.addAll(deptIdList);
        }
        if(!CollectionUtils.isEmpty(scopeDeptIdList)){
            deptIds.addAll(scopeDeptIdList);
        }
        if(CollectionUtils.isEmpty(deptIds)){
            return Sets.newHashSet();
        }
        List<SysDepartPO> poList = sysDeptDAO.findIn(SysDepartPO::getDepartCode, deptIds);
        return poList.stream().map(SysDepartPO::getDepartCode).collect(Collectors.toSet());
    }

    private String decodeStr(String encodeStr){
        if(StringUtils.isBlank(encodeStr)){
            return null;
        }
        return Base64.decodeStr(encodeStr);
    }


    private boolean isPassword(String password){
        if(StringUtils.isBlank(password)){
            return false;
        }
        String pattern = "^(?=.*[0-9])(?=.*[a-zA-Z])[!-~]{8,20}$";
        return ReUtil.isMatch(pattern, password);
    }


}
